/**
 * 
 */
package com.googlecode.gauth.sites.impl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.http.RequestToken;

import com.googlecode.gauth.beans.User;
import com.googlecode.gauth.sites.Site;
import com.googlecode.gauth.sites.SiteUserService;

/**
 * @author asanthan
 * 
 * https://github.com/yusuke/sign-in-with-twitter
 * 
 */
public class TwitterUserService implements SiteUserService {

	private static final String TWITTER_LOGGED_IN = "gauth.tLoggedin";
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.gauth.service.UserService#isLoggedIn(javax.servlet.http
	 * .HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public boolean isLoggedIn(HttpServletRequest pRequest, HttpServletResponse pResponse) {
		Twitter twitter = (Twitter) pRequest.getSession().getAttribute("twitter");
		try {
			return twitter.verifyCredentials()!=null;
		} catch (TwitterException e) {
			throw new RuntimeException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.gauth.service.UserService#isAdmin(javax.servlet.http.
	 * HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public boolean isAdmin(HttpServletRequest pRequest, HttpServletResponse pResponse) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.gauth.service.UserService#getLoggedInUser(javax.servlet
	 * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public User getLoggedInUser(HttpServletRequest pRequest, HttpServletResponse pResponse) {
		Twitter twitter = (Twitter) pRequest.getSession().getAttribute("twitter");
		twitter4j.User userBean;
		try {
			userBean = twitter.verifyCredentials();
		} catch (TwitterException e) {
			throw new RuntimeException(e);
		}
		User user = new User(userBean.getName(), "", userBean.getName(), null, userBean.getId()+"");
		return user;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.gauth.service.UserService#getLoginInUrl(javax.servlet.
	 * http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public String getLoginInUrl(HttpServletRequest pRequest, HttpServletResponse pResponse) {
		Twitter twitter = new Twitter();
		pRequest.getSession().setAttribute("twitter", twitter);
        try {
        	String callBackUrl = (String)pRequest.getAttribute("callBack");
        	RequestToken requestToken = null;
        	if(callBackUrl == null) {
        		requestToken = twitter.getOAuthRequestToken();
        	} else {
        		requestToken = twitter.getOAuthRequestToken(callBackUrl);
        	}
            
            pRequest.getSession().setAttribute("requestToken", requestToken);
            String authenticationURL = requestToken.getAuthenticationURL();
            
            // this returns something similar to 
            // http://twitter.com/oauth/authenticate?oauth_token=NT1Xlm0owGxMxhI1MAz4KXBelUEb6bqWhpaUevfgU
            // the above doesn't even ask the user. It would just login to our app if user is already logged in.
            
            // http://twitter.com/oauth/authorize?oauth_token=NT1Xlm0owGxMxhI1MAz4KXBelUEb6bqWhpaUevfgU is also valid
            // This will explicitly ask the user whether he wants to give access.
            return authenticationURL;

        } catch (TwitterException e) {
            throw new RuntimeException(e);
        }
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.gauth.service.UserService#getLogOutUrl(javax.servlet.http
	 * .HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public String getLogOutUrl(HttpServletRequest pRequest, HttpServletResponse pResponse) {
		// No logout. Simply clear the session (session.invalidate())
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.gauth.sites.SiteUserService#getSiteInformation()
	 */
	@Override
	public Site getSiteInformation() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean processCallBack(HttpServletRequest request,
			HttpServletResponse pResponse) {
		Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
        RequestToken requestToken = (RequestToken) request.getSession().getAttribute("requestToken");
        String verifier = request.getParameter("oauth_verifier");
        try {
            twitter.getOAuthAccessToken(requestToken, verifier);
            if(twitter.getUserId()!=null) {
            	request.getSession().setAttribute(TWITTER_LOGGED_IN,Boolean.TRUE);
            }
            request.getSession().removeAttribute("requestToken");
        } catch (TwitterException e) {
            throw new RuntimeException(e);
        }
        
		return true;
	}

}
